package com.annhoa.infrastructure.util.aes;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.http.MediaType;

import javax.servlet.http.HttpServletRequest;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;

@Slf4j
public class SignUtil {

    /**
     * // 用于服务层校验
     * 校验时间戳
     *
     * @param timestamp
     */
    private static void checkSignTime(String timestamp) {
        if (StringUtils.isBlank(timestamp)) {
            log.error("{}-鉴权时间戳缺失", "");
            throw new RuntimeException("鉴权时间戳缺失");
        }
        // 统一都传毫秒
        long currentTime = System.currentTimeMillis();
        long requestTime = 0;
        try {
            requestTime = Long.parseLong(timestamp);
        } catch (NumberFormatException e) {
            log.error("{}-鉴权时间戳错误 timestamp:{}", "", timestamp);
            throw new RuntimeException("鉴权时间戳错误");
        }
        if (Math.abs(currentTime - requestTime) / 1000 > 30 * 60 * 100) {
            log.error("{}-签名已过期，服务器当前时间:{}", "", currentTime);
            throw new RuntimeException("签名已过期，服务器当前时间" + currentTime);
        }

    }

    // 用于服务层校验
    public static void verifySign(String content, String appKey, String timestamp, String sign) throws Exception {
        if (StringUtils.isBlank(sign)) {
            throw new RuntimeException("");
        }
        checkSignTime(timestamp);
        // 验证签名
        String streamStr = Base64Utils.encode(content.getBytes());
        if (!SignUtil.checkSign(streamStr, appKey, timestamp, sign)) {
            log.error("{}-签名错误", "");
            throw new RuntimeException("签名错误");
        }
    }


    /**
     * @param content         验签内容
     * @param key             签名key值
     * @param additionContent 附加的签名信息
     * @param sign            待验证的签名
     * @Description 验证签名
     */
    public static boolean checkSign(String content, String key, String additionContent, String sign) {
        if (StringUtils.isBlank(sign)) {
            return false;
        }
        String sign_ = createSign(content, key, additionContent);
        if (sign.equalsIgnoreCase(sign_)) {
            return true;
        }
        log.error("参数sign：{}，验签sign:{}", sign, sign_);
        return false;
    }

    /**
     * @param content         签名内容
     * @param key             签名key值
     * @param additionContent 附加条件
     * @Description 生成签名
     */
    public static String createSign(String content, String key, String additionContent) {
        if (StringUtils.isEmpty(additionContent)) {
            return Md5Utils.hash(content + key);
        } else {
            return Md5Utils.hash(content + key + additionContent);
        }
    }

    /**
     *      * 判断本次请求的数据类型是否为json
     *      *
     *      * @param request request
     *      * @return true: 是 JSON 数据; false: 非 json 数据
     *      
     */
    public static boolean isJson(HttpServletRequest request) {
        if (request.getContentType() != null) {
            return request.getContentType().equals(MediaType.APPLICATION_JSON_VALUE) ||
                    request.getContentType().equals(MediaType.APPLICATION_JSON_UTF8_VALUE);
        }
        return false;
    }


    /**
     * 获取请求Body
     *
     * @param request
     * @return
     */
    public static String getBodyString(HttpServletRequest request) {
        StringBuilder sb = new StringBuilder();
        try (InputStream inputStream = request.getInputStream();
             BufferedReader reader = new BufferedReader(
                     new InputStreamReader(inputStream, StandardCharsets.UTF_8))) {
            String line;
            while ((line = reader.readLine()) != null) {
                sb.append(line);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return sb.toString();
    }
}
